package com.yyfax.pay.third.facade.fuiou;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.SocketTimeoutException;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import com.yyfax.framework.common.Log;
import com.yyfax.pay.third.model.to.fuiou.*;
import com.yyfax.pay.third.model.to.yyfax.*;
import org.apache.commons.lang.NotImplementedException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSON;
import com.yyfax.commons.json.JacksonUtil;
import com.yyfax.framework.yyfax.enums.RspCodeEnum;
import com.yyfax.pay.common.constants.FuiouRespConstant;
import com.yyfax.pay.common.constants.PayConstants;
import com.yyfax.pay.common.enums.PayModeEnum;
import com.yyfax.pay.common.enums.PayRspCodeEnum;
import com.yyfax.pay.common.enums.PayTypeEnum;
import com.yyfax.pay.common.enums.PaymentEnum;
import com.yyfax.pay.common.exception.PayExceptionCode;
import com.yyfax.pay.common.exception.YYPayException;
import com.yyfax.pay.common.util.CommonIdUtils;
import com.yyfax.pay.config.data.service.MerchantPaymentService;
import com.yyfax.pay.config.model.po.MerchantPaymentPO;
import com.yyfax.pay.order.model.vo.PayBusiIdVO;
import com.yyfax.pay.third.model.to.fuiou.xml.PayoutOrderFuiouContent;
import com.yyfax.pay.third.model.to.fuiou.xml.QueryPayoutOrderFuiouContent;
import com.yyfax.pay.third.service.PayInfoConstantService;
import com.yyfax.pay.third.service.ThirdPayService;
import com.yyfax.pay.third.service.TransformService;

/**
 * 富友支付
 *
 * @author heizq
 * @date 2017-04-21 10:52:53
 * @since v1.0.0
 */
public class FuiouFacade extends ThirdPayService {

	Logger logger = LoggerFactory.getLogger(getClass());

	@Resource(name = "fuiouTransformService")
	private TransformService transformService;

	@Resource
	private FuiouTransformService fuiouTransformService;

	@Autowired
	private MerchantPaymentService merchantPaymentService;

	@Autowired
	private PayInfoConstantService fuiouPayInfoService;

	@Resource
	private FuiouApi fuiouApi;

	@Autowired
	private PayConstants payConstants;

	@PostConstruct
	private void init() {
		this.facadeName = "富友";
	}

	@Override
	public QueryPayOrderYYContent queryOrder(QueryPayOrderYYParams req) throws Exception {
		QueryOrderByOrderNumFuiouParams queryOrderByOrderNumFuiouParams = null;
		QueryOrderByOrderNumFuiouContent queryOrderByOrderNumFuiouContent = null;
		QueryPayOrderYYContent queryPayOrderYYContent = null;
		try {
			// 转换成富友查询请求参数
			queryOrderByOrderNumFuiouParams = transformService.transformQueryPayOrderParams(req);

			queryOrderByOrderNumFuiouParams.validate();

			queryOrderByOrderNumFuiouContent = fuiouApi.searchOrderByMchtOrderId(queryOrderByOrderNumFuiouParams);

			queryPayOrderYYContent = transformService.transformQueryPayOrderContent(queryOrderByOrderNumFuiouContent);
		} catch (Exception e) {
			queryPayOrderYYContent = new QueryPayOrderYYContent();
			logger.error("【pay】【FUIOU】查询订单失败，订单号：" + req.getPayOrderId(), e);
			if (e instanceof YYPayException) {
				YYPayException excp = (YYPayException) e;
				queryPayOrderYYContent.setResultCode(excp.getCode());
				queryPayOrderYYContent.setResultMsg(StringUtils.isBlank(excp.getMessage()) ? excp.getDisplay() : excp.getMessage());
			} else {
				queryPayOrderYYContent.setResultCode(PayRspCodeEnum.PAY_CODE_UNKNOWN.getValue());
				queryPayOrderYYContent.setResultMsg("查询订单失败");
			}
		}

		if (queryOrderByOrderNumFuiouParams != null) {
			queryPayOrderYYContent.setReqContent(JSON.toJSONString(queryOrderByOrderNumFuiouParams.getParams()));
			queryPayOrderYYContent.setReqUrl(queryOrderByOrderNumFuiouParams.getUrl());
		}
		return queryPayOrderYYContent;
	}

	@Override
	public SendAuthenticationVerifyCodeYYContent sendAuthenticationVerifyCode(SendAuthenticationVerifyCodeYYParams req) throws Exception {
		throw new NotImplementedException("富友支付不支持");
	}

	@Override
	public AuthenticationYYContent authentication(AuthenticationYYParams req) throws Exception {
		throw new NotImplementedException("富友支付不支持");
	}

	/**
	 * 独立鉴权-直连 ，参数校验，调用富有接口
	 *
	 * @param req
	 * @return
	 * @author xulqb
	 * @date 2017-12-21 15:47
	 * @since V1.0.0
	 */
	@Override
	public WithoutVerifyYYContent authenticationWithout(WithoutVerifyYYParams req) throws Exception {

		WithoutVerifyFuiouParams withoutVerifyFuiouParams = null;
		WithoutVerifyFuiouContent withoutVerifyFuiouContent;
		WithoutVerifyYYContent content;

		try {
			withoutVerifyFuiouParams = transformService.transformWithoutVerifyParams(req);

			withoutVerifyFuiouParams.validate();

			withoutVerifyFuiouContent = fuiouApi.withoutVerify(withoutVerifyFuiouParams);
			withoutVerifyFuiouContent.setMerchentId(req.getMerchantCode());

			content = transformService.transformWithoutVerifyContent(withoutVerifyFuiouContent);
		} catch (Exception e) {
			content = new WithoutVerifyYYContent();
			logger.info(Log.op("FuiouFacade.authenticationWithout").msg("调用富有接口失败").kv("req", req).toString(), e);
			if (e instanceof YYPayException) {
				YYPayException excp = (YYPayException) e;
				content.setResultCode(excp.getCode());
				content.setResultMsg(StringUtils.isBlank(excp.getMessage()) ? excp.getDisplay() : excp.getMessage());
			} else {
				content.setResultCode(PayRspCodeEnum.PAY_CODE_UNKNOWN.getValue());
				content.setResultMsg("调用富有接口失败");
			}
		}

		content.setUserId(req.getUserId());
		if (withoutVerifyFuiouParams != null) {
			content.setReqUrl(withoutVerifyFuiouParams.getUrl());
		}
		return content;
	}

	@Override
	public SendVerifyCodeYYContent sendVerifyCode(SendVerifyCodeYYParams req) throws Exception {

		// 普通认证支付
		return sendAuthVerifyCode(req);

		// // 首次协议支付
		// if (StringUtils.isBlank(req.getProtocolNo()) && !req.isAgain()) {
		// return sendProtocolVerifyCode(req);
		// }
		//
		// // 再次协议支付
		// if (!StringUtils.isBlank(req.getProtocolNo()) && req.isAgain()) {
		// return sendProtocolAgainVerifyCode(req);
		// }
	}

	@Override
	public PayOrderYYContent payOrder(PayOrderYYParams req) throws Exception {

		// 普通认证支付
		return payAuthOrder(req);

		// // 协议支付首次
		// if (StringUtils.isBlank(req.getProtocolNo()) && !req.isAgain()) {
		// return protocolPayOrder(req);
		// }
		//
		// // 协议支付再次次
		// if (!StringUtils.isBlank(req.getProtocolNo()) && req.isAgain()) {
		// return protocolAgainPayOrder(req);
		// }
	}

	@Override
	public PayoutOrderYYContent payoutOrder(PayoutOrderYYParams req) throws Exception {
		PayoutOrderYYContent content = new PayoutOrderYYContent();
		try {
			// step1.转换成富友代付的请求参数
			PayoutOrderFuiouParams payoutOrderParams = transformService.transformPayoutOrderParams(req);

			// step2.发起富友代付请求
			PayoutOrderFuiouContent payoutOrderContent = fuiouApi.payout(payoutOrderParams);

			// step3.转换富友代付响应参数为支付模块的代付响应参数
			content = transformService.transformPayoutOrderContent(payoutOrderContent);

			return content;
		} catch (SocketTimeoutException e) {
			// 请求超时
			content.setResultCode(PayRspCodeEnum.PAY_CODE_REQ_TIME_OUT.getValue());
			content.setResultMsg(PayRspCodeEnum.PAY_CODE_REQ_TIME_OUT.getRemark());
		} catch (Exception e) {
			content.setResultCode(PayRspCodeEnum.PAY_CODE_PAYOUT_FAIL.getValue());
			content.setResultMsg(PayRspCodeEnum.PAY_CODE_PAYOUT_FAIL.getRemark());
		}

		return content;
	}

	/**
	 * 富友代付新入口
	 * 
	 * @author buyi
	 * @date 2018-05-12 02:19:02
	 * @since v2.1.5
	 * @param req
	 * @param binder
	 * @throws Exception
	 */
	@Override
	protected void payoutOrderNew(PayoutOrderYYParams req, PayoutDataBinder binder) throws Exception {
		// step1.转换成富友代付的请求参数
		PayoutOrderFuiouParams payoutOrderParams = transformService.transformPayoutOrderParams(req);

		// step2.发起富友代付请求
		PayoutOrderFuiouContent payoutOrderContent = fuiouApi.payoutNew(payoutOrderParams, binder);

		// step3.转换富友代付响应参数为支付模块的代付响应参数
		if (payoutOrderContent.isSuccess()) {
			binder.setResult(PayExceptionCode.SUCCESS);
		} else {
			binder.setResult(PayExceptionCode.ERROR_PAYOUT_FAIL);
		}
	}

	@Override
	public PayoutBatchOrderYYContent payoutBatchOrder(PayoutBatchOrderYYParams req) throws Exception {
		throw new NotImplementedException("富友支付不支持");
	}

	@Override
	public QueryBatchPayoutOrderYYContent queryBatchPayoutOrder(QueryBatchPayoutOrderYYParams req) throws Exception {
		throw new NotImplementedException("富友支付不支持");
	}

	@Override
	public QueryBatchPayoutOrderCheckYYContent batchPayoutOrderCheck(QueryBatchPayoutOrderCheckYYParams req) throws Exception {
		throw new NotImplementedException("富友支付不支持");
	}

	@Override
	public QueryCardBinContent queryCardBin(QueryCardBinParams req) throws Exception {
		QueryCardBinContent content = null;
		// 富友卡bin查询
		FuiouBaseReqVO cardBinReqVO = fuiouTransformService.transformQueryCardBinParams(req);
		try {
			String rspStr = fuiouApi.cardBin(cardBinReqVO);

			content = fuiouTransformService.transformQueryCardBinContent(rspStr);

		} catch (SocketTimeoutException e) {
			logger.error("【富友】【卡bin】查询超时", e);
			content = new QueryCardBinContent();
			content.setResultCode(PayRspCodeEnum.PAY_CODE_REQ_TIME_OUT.getValue());
			content.setResultMsg(PayRspCodeEnum.PAY_CODE_REQ_TIME_OUT.getRemark());
		}

		return content;
	}

	@Override
	public WebFormYYContent<PayWebFormContent> transformWebForm(WebFormYYParams req) throws Exception {
		WebFormYYContent<PayWebFormContent> content = new WebFormYYContent<PayWebFormContent>();
		PayWebFormContent payWebFormContent = new PayWebFormContent();

		payWebFormContent.setPayOrderId(req.getPayOrderId());
		payWebFormContent.setMerchantCode(req.getMerchantCode());
		payWebFormContent.setPaymentCode(req.getPaymentCode());

		// 设置签名
		payWebFormContent.setSign(payWebFormContent.sign(payConstants.getSignKey()));

		content.setUrl(payConstants.getCounterUrl());
		content.setNotifyUrl(String.format(payConstants.getNotifyUrl(), req.getPaymentCode()));
		content.setForm(payWebFormContent);
		return content;
	}

	@Override
	public OrderReturnContent transformPayOrderReturn(HttpServletRequest request) throws Exception {
		StringBuilder sb = new StringBuilder();
		try {
			try (BufferedReader in = new BufferedReader(new InputStreamReader(request.getInputStream()))) {
				String line = null;
				while ((line = in.readLine()) != null) {
					sb.append(line);
				}
				PayReturnParams payReturnParams = JacksonUtil.nonullMapper.fromJson(sb.toString(), PayReturnParams.class);
				if (payReturnParams == null) {
					throw new YYPayException(RspCodeEnum.COMMON_ERROR_NO_SIGN_AUTHENTICATION.getValue(), "请求参数为空");
				}
				OrderReturnContent orderReturnContent = new OrderReturnContent();
				orderReturnContent.setResultCode(payReturnParams.getResultCode());
				orderReturnContent.setResultMsg(payReturnParams.getResultMsg());
				orderReturnContent.setPayOrderId(payReturnParams.getPayOrderId());
				orderReturnContent.setSerialNo(payReturnParams.getSerialNo());
				return orderReturnContent;
			}
		} catch (RuntimeException e) {
			logger.error("【pay】【FUIOU】同步响应处理失败。returnContent：" + sb.toString(), e);
			throw new YYPayException(PayRspCodeEnum.COMMON_ERROR_UNKNOWN_EXCEPTION.getValue(), "异步通知处理失败");
		}
	}

	@Override
	public OrderNotifyContent transformPayOrderNotify(HttpServletRequest request) throws Exception {
		PayOrderNoticeFuiouContent noticeContent = null;

		try {
			noticeContent = createNoticeContent(request);
			PayBusiIdVO payOrderIdVo = CommonIdUtils.getPayBusiIdVo(noticeContent.getMchntorderid());
			FuiouExtConstant fuiouConstant = fuiouPayInfoService.getMerchantInfo(FuiouExtConstant.class, payOrderIdVo.getMerchantCode(),
					PaymentEnum.FUIOU, PayTypeEnum.PAY, PayModeEnum.AUTH_PAY);

			OrderNotifyContent content = new OrderNotifyContent();
			if (((FuiouTransformService) transformService).validateSign(noticeContent, fuiouConstant)) {
				if (FuiouRespConstant.RESPONSECODE_SUCCESS.equals(noticeContent.getResponsecode())) {
					content.setResultCode(PayRspCodeEnum.SUCCESS.getValue());
					content.setResultMsg(noticeContent.getResponsemsg());
				} else {
					logger.info("【pay】【FUIOU】富友支付异步通知失败！orderId:{},amount:{},msg:{}", noticeContent.getMchntorderid(), noticeContent.getAmt(),
							noticeContent.getResponsemsg());
					// 短信发送频繁,或者验证码异常
					if (StringUtils.equals(noticeContent.getResponsecode(), FuiouRespConstant.SEND_VALIDATE_CODE_FREQUENT)
							|| StringUtils.equals(noticeContent.getResponsecode(), FuiouRespConstant.VALIDATE_CODE_ERROR)) {
						content.setResultCode(PayRspCodeEnum.PAY_CODE_VALID_CODE_EXPIRE.getValue());
						content.setResultMsg(noticeContent.getResponsemsg());
					} else {
						content.setResultCode(PayRspCodeEnum.PAY_CODE_PAY_FAIL.getValue());
						// 响应信息要具体
						content.setResultMsg("交易失败，商户通道：" + noticeContent.getResponsemsg());
					}

				}
			} else {
				content.setResultCode(PayRspCodeEnum.PAY_CODE_CHECK_SIGN_FAIL.getValue());
				content.setResultMsg("异步回调验签失败");
				logger.error("【pay】【FUIOU】富友支付异步返回验签失败！orderId:{},amount:{}", noticeContent.getMchntorderid(), noticeContent.getAmt());
			}
			content.setSerialNo(noticeContent.getOrderid());
			content.setPayOrderId(noticeContent.getMchntorderid());

			content.setReqContent(noticeContent.toString());
			content.setRspContent("");
			content.setAmount(Integer.valueOf(noticeContent.getAmt()));
			logger.info("【pay】【FUIOU】异步通知处理成功。noticeContent:{}", noticeContent.toString());
			return content;
		} catch (RuntimeException e) {
			logger.error("【pay】【FUIOU】异步通知处理失败。noticeContent：" + noticeContent, e);
			throw new YYPayException(PayRspCodeEnum.COMMON_ERROR_UNKNOWN_EXCEPTION.getValue(), "异步通知处理失败");
		}
	}

	/**
	 * 封装异步回调实体
	 *
	 * @param request
	 * @return
	 * @author heizq
	 * @date 2017-04-16 11:14:53
	 * @since v1.0.0
	 */
	private PayOrderNoticeFuiouContent createNoticeContent(HttpServletRequest request) {
		String version = request.getParameter("VERSION");
		String type = request.getParameter("TYPE");
		String responseCode = request.getParameter("RESPONSECODE");
		String responseMsg = request.getParameter("RESPONSEMSG");
		String mchntCd = request.getParameter("MCHNTCD");
		String mchntOrderId = request.getParameter("MCHNTORDERID");
		String orderId = request.getParameter("ORDERID");
		String bankCard = request.getParameter("BANKCARD");
		String amt = request.getParameter("AMT");
		String sign = request.getParameter("SIGN");
		String protocolNo = request.getParameter("PROTOCOLNO");

		PayOrderNoticeFuiouContent content = new PayOrderNoticeFuiouContent();
		content.setVersion(version);
		content.setType(type);
		content.setResponsecode(responseCode);
		content.setResponsemsg(responseMsg);
		content.setMchntcd(mchntCd);
		content.setMchntorderid(mchntOrderId);
		content.setOrderid(orderId);
		content.setBankcard(bankCard);
		content.setAmt(amt);
		content.setSign(sign);
		content.setProtocolNo(protocolNo);
		return content;
	}

	@Override
	public OrderNotifyContent transformPayoutOrderNotify(HttpServletRequest request) throws Exception {
		throw new NotImplementedException("富友支付不支持");
	}

	@Override
	public QueryPayoutOrderYYContent queryPayoutOrder(QueryPayoutOrderYYParams req) throws Exception {
		throw new NotImplementedException("富友代付不支持");
		// final String op = "FuiouFacade.queryPayoutOrder";
		// QueryPayoutOrderYYContent transformContent;
		// try {
		// QueryPayoutOrderFuiouParams params = transformService.transformQueryPayOutOrderParams(req);
		// QueryPayoutOrderFuiouContent content = fuiouApi.queryPayOutOrder(params);
		// transformContent = transformService.transformQueryPayOutOrderContent(content);
		// transformContent.setReqUrl(params.getUrl());
		// } catch(Exception e) {
		// logger.error(Log.op(op).msg("富友查询代付异常").kv("请求参数", req).toString(), e);
		// transformContent = new QueryPayoutOrderYYContent();
		// if(e instanceof YYPayException) {
		// YYPayException ye = (YYPayException) e;
		// transformContent.setResultCode(ye.getCode());
		// transformContent.setResultMsg(StringUtils.isNotEmpty(ye.getDisplay()) ? ye.getDisplay() : "未知异常");
		// } else {
		// transformContent.setResultCode(PayRspCodeEnum.PAY_CODE_UNKNOWN.getValue());
		// transformContent.setResultMsg("未知异常");
		// }
		// }
		// transformContent.setUserId(req.getUserId());
		// transformContent.setOrderId(req.getOrderId());
		// return transformContent;
	}

	@Override
	public MerchantConfigExtContent queryMerchantConfigExt(String merchantCode, PayTypeEnum paytType, PayModeEnum payMode) throws Exception {
		MerchantPaymentPO merchant = merchantPaymentService.queryByThirdMerchantCode(merchantCode, PaymentEnum.FUIOU.getValue(), paytType.getValue(),
				payMode.getValue());

		FuiouExtConstant fuiouConstan = null;
		if (merchant == null) {
			logger.error("【pay】【FUIOU】查询支付通过信息失败,商户信息为空,merchantCode:{}", merchantCode);
			throw new YYPayException(RspCodeEnum.COMMON_ERROR_OBJECT_NOT_FOUND.getValue(), "查询支付通过信息失败,商户信息为空.");
		}
		if (StringUtils.isNotBlank(merchant.getExt())) {
			fuiouConstan = JacksonUtil.nonullMapper.fromJson(merchant.getExt(), FuiouExtConstant.class);
		} else {
			logger.error("【pay】【FUIOU】支付商户扩展信息为空,merchantCode:{}", merchantCode);
			throw new YYPayException(RspCodeEnum.COMMON_ERROR_OBJECT_NOT_FOUND.getValue(), "支付通过扩展信息为空");
		}
		logger.info("【pay】【FUIOU】查询支付通过信息成功,merchant:{}", JacksonUtil.nonullMapper.toJson(merchant));
		fuiouConstan.setMerchantId(merchant.getPayMerchantId());

		MerchantConfigExtContent extContent = new MerchantConfigExtContent();
		extContent.setFormUrl(fuiouConstan.getActionUrl());

		return extContent;
	}

	/**
	 * 认证支付获取验证码
	 *
	 * @param req
	 * @return
	 * @throws Exception
	 * @author heizq
	 * @date 2017-05-22 10:17:02
	 * @since v1.2.0
	 */
	public SendVerifyCodeYYContent sendAuthVerifyCode(SendVerifyCodeYYParams req) throws Exception {

		PlaceOrderFuiouParams placeOrderFuiouParams = null;
		PlaceOrderFuiouContent placeOrderFuiouContent = null;
		SendVerifyCodeYYContent content = null;

		try {
			placeOrderFuiouParams = transformService.transformSendVerifyCodeParams(req);

			placeOrderFuiouParams.validate();

			placeOrderFuiouContent = fuiouApi.placeOrder(placeOrderFuiouParams);

			content = transformService.transformSendVerifyCodeContent(placeOrderFuiouContent);
		} catch (Exception e) {
			content = new SendVerifyCodeYYContent();
			logger.error("【pay】【FUIOU】查询订单失败，订单号：" + req.getPayOrderId(), e);
			if (e instanceof YYPayException) {
				YYPayException excp = (YYPayException) e;
				content.setResultCode(excp.getCode());
				content.setResultMsg(StringUtils.isBlank(excp.getMessage()) ? excp.getDisplay() : excp.getMessage());
			} else {
				content.setResultCode(PayRspCodeEnum.PAY_CODE_UNKNOWN.getValue());
				content.setResultMsg("查询订单失败");
			}
		}

		content.setUserId(req.getUserId());
		if (placeOrderFuiouParams != null) {
			content.setReqUrl(placeOrderFuiouParams.getUrl());
			content.setReqContent(JSON.toJSONString(placeOrderFuiouParams.getLogParams()));
		}
		return content;
	}

	/**
	 * 认证支付
	 *
	 * @param req
	 * @return
	 * @throws Exception
	 * @author heizq
	 * @date 2017-05-22 10:22:45
	 * @since v1.2.0
	 */
	public PayOrderYYContent payAuthOrder(PayOrderYYParams req) throws Exception {

		PayOrderFuiouParams payOrderFuiouParams = null;
		PayOrderFuiouContent payOrderFuiouContent = null;
		PayOrderYYContent content = null;
		try {
			payOrderFuiouParams = transformService.transformPayOrdeParams(req);

			payOrderFuiouContent = fuiouApi.pay(payOrderFuiouParams);

			content = transformService.transformPayOrdeContent(payOrderFuiouContent);
		} catch (Exception e) {
			content = new PayOrderYYContent();
			logger.error("【pay】【FUIOU】查询订单失败，订单号：" + req.getPayOrderId(), e);
			if (e instanceof YYPayException) {
				YYPayException excp = (YYPayException) e;
				content.setResultCode(excp.getCode());
				content.setResultMsg(StringUtils.isBlank(excp.getMessage()) ? excp.getDisplay() : excp.getMessage());
			} else {
				content.setResultCode(PayRspCodeEnum.PAY_CODE_UNKNOWN.getValue());
				content.setResultMsg("查询订单失败");
			}
		}

		if (payOrderFuiouParams != null) {
			content.setReqContent(JSON.toJSONString(payOrderFuiouParams.getLogParams()));
			content.setReqUrl(payOrderFuiouParams.getUrl());
		}
		content.setPayOrderId(req.getPayOrderId());
		content.setUserId(req.getUserId());
		return content;
	}

	/**
	 * 首次协议支付获取验证码
	 *
	 * @param req
	 * @return
	 * @throws Exception
	 * @author heizq
	 * @date 2017-05-15 16:17:52
	 * @since v1.2.0
	 */
	public SendVerifyCodeYYContent sendProtocolVerifyCode(SendVerifyCodeYYParams req) throws Exception {

		ProtocolPlaceOrderFuiouParams placeOrderFuiouParams = null;
		ProtocolPlaceOrderFuiouContent placeOrderFuiouContent = null;
		SendVerifyCodeYYContent content = null;

		try {
			placeOrderFuiouParams = fuiouTransformService.transformProtocolSendVerifyCodeParams(req);

			placeOrderFuiouContent = fuiouApi.protocolPlaceOrder(placeOrderFuiouParams);

			content = fuiouTransformService.transformProtocolSendVerifyCodeContent(placeOrderFuiouContent);
		} catch (Exception e) {
			content = new SendVerifyCodeYYContent();
			logger.error("【pay】【FUIOU】查询订单失败，订单号：" + req.getPayOrderId(), e);
			if (e instanceof YYPayException) {
				YYPayException excp = (YYPayException) e;
				content.setResultCode(excp.getCode());
				content.setResultMsg(StringUtils.isBlank(excp.getMessage()) ? excp.getDisplay() : excp.getMessage());
			} else {
				content.setResultCode(PayRspCodeEnum.PAY_CODE_UNKNOWN.getValue());
				content.setResultMsg("查询订单失败");
			}
		}

		content.setUserId(req.getUserId());
		if (placeOrderFuiouParams != null) {
			content.setReqUrl(placeOrderFuiouParams.getUrl());
			content.setReqContent(JSON.toJSONString(placeOrderFuiouParams.getLogParams()));
		}
		return content;
	}

	/**
	 * 首次协议支付获取验证码重发
	 *
	 * @param req
	 * @return
	 * @throws Exception
	 * @author heizq
	 * @date 2017-05-15 16:17:52
	 * @since v1.2.0
	 */
	public SendVerifyCodeYYContent sendProtocolRetryVerifyCode(SendVerifyCodeYYParams req) throws Exception {

		ProtocolPlaceOrderRetryFuiouParams placeOrderFuiouParams = null;
		ProtocolPlaceOrderRetryFuiouContent placeOrderFuiouContent = null;
		SendVerifyCodeYYContent content = null;

		try {
			placeOrderFuiouParams = fuiouTransformService.transformProtocolRetrySendVerifyCodeParams(req);

			placeOrderFuiouContent = fuiouApi.protocolPlaceOrderRetry(placeOrderFuiouParams);

			content = fuiouTransformService.transformProtocolRetrySendVerifyCodeContent(placeOrderFuiouContent);
		} catch (Exception e) {
			content = new SendVerifyCodeYYContent();
			logger.error("【pay】【FUIOU】查询订单失败，订单号：" + req.getPayOrderId(), e);
			if (e instanceof YYPayException) {
				YYPayException excp = (YYPayException) e;
				content.setResultCode(excp.getCode());
				content.setResultMsg(StringUtils.isBlank(excp.getMessage()) ? excp.getDisplay() : excp.getMessage());
			} else {
				content.setResultCode(PayRspCodeEnum.PAY_CODE_UNKNOWN.getValue());
				content.setResultMsg("查询订单失败");
			}
		}

		content.setUserId(req.getUserId());
		if (placeOrderFuiouParams != null) {
			content.setReqUrl(placeOrderFuiouParams.getUrl());
			content.setReqContent(JSON.toJSONString(placeOrderFuiouParams.getLogParams()));
		}
		return content;
	}

	/**
	 * 再次协议支付获取验证码
	 *
	 * @param req
	 * @return
	 * @throws Exception
	 * @author heizq
	 * @date 2017-05-15 16:17:52
	 * @since v1.2.0
	 */
	public SendVerifyCodeYYContent sendProtocolAgainVerifyCode(SendVerifyCodeYYParams req) throws Exception {

		ProtocolPlaceOrderAgainFuiouParams placeOrderFuiouParams = null;
		ProtocolPlaceOrderAgainFuiouContent placeOrderFuiouContent = null;
		SendVerifyCodeYYContent content = null;

		try {
			placeOrderFuiouParams = fuiouTransformService.transformProtocolAgainSendVerifyCodeParams(req);

			placeOrderFuiouContent = fuiouApi.protocolPlaceOrderAgain(placeOrderFuiouParams);

			content = fuiouTransformService.transformProtocolAgainSendVerifyCodeContent(placeOrderFuiouContent);
		} catch (Exception e) {
			content = new SendVerifyCodeYYContent();
			logger.error("【pay】【FUIOU】查询订单失败，订单号：" + req.getPayOrderId(), e);
			if (e instanceof YYPayException) {
				YYPayException excp = (YYPayException) e;
				content.setResultCode(excp.getCode());
				content.setResultMsg(StringUtils.isBlank(excp.getMessage()) ? excp.getDisplay() : excp.getMessage());
			} else {
				content.setResultCode(PayRspCodeEnum.PAY_CODE_UNKNOWN.getValue());
				content.setResultMsg("查询订单失败");
			}
		}

		content.setUserId(req.getUserId());
		if (placeOrderFuiouParams != null) {
			content.setReqUrl(placeOrderFuiouParams.getUrl());
			content.setReqContent(JSON.toJSONString(placeOrderFuiouParams.getLogParam()));
		}
		return content;
	}

	/**
	 * 再次协议支付获取验证码重发
	 *
	 * @param req
	 * @return
	 * @throws Exception
	 * @author heizq
	 * @date 2017-05-15 16:17:52
	 * @since v1.2.0
	 */
	public SendVerifyCodeYYContent sendProtocolAgainRetryVerifyCode(SendVerifyCodeYYParams req) throws Exception {

		ProtocolPlaceOrderAgainRetryFuiouParams placeOrderFuiouParams = null;
		ProtocolPlaceOrderAgainRetryFuiouContent placeOrderFuiouContent = null;
		SendVerifyCodeYYContent content = null;

		try {
			placeOrderFuiouParams = fuiouTransformService.transformProtocolAgainReSendVerifyCodeParams(req);

			placeOrderFuiouContent = fuiouApi.protocolPlaceOrderAgainRetry(placeOrderFuiouParams);

			content = fuiouTransformService.transformProtocolAgainReSendVerifyCodeContent(placeOrderFuiouContent);
		} catch (Exception e) {
			content = new SendVerifyCodeYYContent();
			logger.error("【pay】【FUIOU】查询订单失败，订单号：" + req.getPayOrderId(), e);
			if (e instanceof YYPayException) {
				YYPayException excp = (YYPayException) e;
				content.setResultCode(excp.getCode());
				content.setResultMsg(StringUtils.isBlank(excp.getMessage()) ? excp.getDisplay() : excp.getMessage());
			} else {
				content.setResultCode(PayRspCodeEnum.PAY_CODE_UNKNOWN.getValue());
				content.setResultMsg("查询订单失败");
			}
		}

		content.setUserId(req.getUserId());
		if (placeOrderFuiouParams != null) {
			content.setReqUrl(placeOrderFuiouParams.getUrl());
			content.setReqContent(JSON.toJSONString(placeOrderFuiouParams.getLogParam()));
		}
		return content;
	}

	/**
	 * 首次协议支付
	 *
	 * @param req
	 * @return
	 * @throws Exception
	 * @author heizq
	 * @date 2017-05-15 17:02:12
	 * @since v1.2.0
	 */
	public PayOrderYYContent protocolPayOrder(PayOrderYYParams req) throws Exception {

		ProtocolPayOrderFuiouParams payOrderFuiouParams = null;
		ProtocolPayOrderFuiouContent payOrderFuiouContent = null;
		PayOrderYYContent content = null;
		try {
			payOrderFuiouParams = fuiouTransformService.transformProtocolPayOrdeParams(req);

			payOrderFuiouContent = fuiouApi.protocolPay(payOrderFuiouParams);

			content = fuiouTransformService.transformProtocolPayOrdeContent(payOrderFuiouContent);
		} catch (Exception e) {
			content = new PayOrderYYContent();
			logger.error("【pay】【FUIOU】查询订单失败，订单号：" + req.getPayOrderId(), e);
			if (e instanceof YYPayException) {
				YYPayException excp = (YYPayException) e;
				content.setResultCode(excp.getCode());
				content.setResultMsg(StringUtils.isBlank(excp.getMessage()) ? excp.getDisplay() : excp.getMessage());
			} else {
				content.setResultCode(PayRspCodeEnum.PAY_CODE_UNKNOWN.getValue());
				content.setResultMsg("查询订单失败");
			}
		}

		if (payOrderFuiouParams != null) {
			content.setReqContent(JSON.toJSONString(payOrderFuiouParams.getLogParam()));
			content.setReqUrl(payOrderFuiouParams.getUrl());
		}
		content.setPayOrderId(req.getPayOrderId());
		content.setUserId(req.getUserId());
		return content;
	}

	/**
	 * 再次协议支付
	 *
	 * @param req
	 * @return
	 * @throws Exception
	 * @author heizq
	 * @date 2017-05-15 17:02:12
	 * @since v1.2.0
	 */
	public PayOrderYYContent protocolAgainPayOrder(PayOrderYYParams req) throws Exception {

		ProtocolPayOrderAgainFuiouParams payOrderFuiouParams = null;
		ProtocolPayOrderAgainFuiouContent payOrderFuiouContent = null;
		PayOrderYYContent content = null;
		try {
			payOrderFuiouParams = fuiouTransformService.transformProtocolAgainPayOrdeParams(req);

			payOrderFuiouContent = fuiouApi.reProtocolPay(payOrderFuiouParams);

			content = fuiouTransformService.transformProtocolAgainPayOrdeContent(payOrderFuiouContent);
		} catch (Exception e) {
			content = new PayOrderYYContent();
			logger.error("【pay】【FUIOU】查询订单失败，订单号：" + req.getPayOrderId(), e);
			if (e instanceof YYPayException) {
				YYPayException excp = (YYPayException) e;
				content.setResultCode(excp.getCode());
				content.setResultMsg(StringUtils.isBlank(excp.getMessage()) ? excp.getDisplay() : excp.getMessage());
			} else {
				content.setResultCode(PayRspCodeEnum.PAY_CODE_UNKNOWN.getValue());
				content.setResultMsg("查询订单失败");
			}
		}

		if (payOrderFuiouParams != null) {
			content.setReqContent(JSON.toJSONString(payOrderFuiouParams.getLogParam()));
			content.setReqUrl(payOrderFuiouParams.getUrl());
		}
		content.setPayOrderId(req.getPayOrderId());
		content.setUserId(req.getUserId());
		return content;
	}
}
